package com.meilai.project.service.workflow.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.meilai.project.dto.workflow.WorkFlowConditionForDepJobDTO;
import com.meilai.project.entity.personnel.org.Department;
import com.meilai.project.entity.system.User;
import com.meilai.project.entity.system.UserDepartmentRelation;
import com.meilai.project.entity.workflow.DictFlowType;
import com.meilai.project.entity.workflow.FormModule;
import com.meilai.project.entity.workflow.WorkFlowDefault;
import com.meilai.project.exception.CommonException;
import com.meilai.project.mapper.workflow.FormModuleMapper;
import com.meilai.project.service.personnel.org.DepartmentService;
import com.meilai.project.service.system.UserDepartmentRelationService;
import com.meilai.project.service.system.UserService;
import com.meilai.project.service.workflow.DictFlowTypeService;
import com.meilai.project.service.workflow.FormModuleService;
import com.meilai.project.service.workflow.WorkFlowDefaultService;
import com.meilai.project.vo.workflow.WorkFlowConditionDataVO;
import com.meilai.project.vo.workflow.WorkFlowDefaultListVO;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import springfox.documentation.spring.web.json.Json;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class FormModuleServiceImpl extends ServiceImpl<FormModuleMapper, FormModule> implements FormModuleService {

    @Autowired
    private WorkFlowDefaultService workFlowDefaultService;

    @Autowired
    private DictFlowTypeService dictFlowTypeService;

    @Autowired
    private UserService userService;

    @Autowired
    private DepartmentService departmentService;

    @Autowired
    private UserDepartmentRelationService userDepartmentRelationService;

    @Override
    public Page<FormModule> pageFuc(Integer pageIndex, Integer page_size, String name, Integer flow_type){
        Page<FormModule> page = new Page<>(pageIndex, page_size);
        List<FormModule> lists = baseMapper.pageFuc(page, name,flow_type);
        return page.setRecords(lists);
    }
    @Override
    public List<List<FormModule>> form_module_list(){
        List<List<FormModule>> res = new ArrayList<>();
        for(int i=1;i<=6;i++){
            List<FormModule> temp = baseMapper.getListByFlow_type(i);
            res.add(temp);
        }
        return res;
    }

    @Override
    public FormModule getByFlowType(Integer flow_type){
        WorkFlowDefault workFlowDefault = workFlowDefaultService.getOne(new QueryWrapper<WorkFlowDefault>().eq("flow_type",flow_type).eq("status",1));
        return baseMapper.selectOne(new QueryWrapper<FormModule>().eq("id",workFlowDefault.getForm_module_id()));
    }




    @Override
    public Page<WorkFlowDefaultListVO> selectPageList(Integer current_page, Integer page_size, String name, Integer status, Integer flow_type) {
        return workFlowDefaultService.selectPageList(current_page, page_size, name, status, flow_type);
    }

    @Override
    public List<DictFlowType> getFlowTypeList() {
        return dictFlowTypeService.list(new QueryWrapper<DictFlowType>().orderByAsc("id"));
    }

    @Override
    public List<WorkFlowConditionDataVO> getAllUserData() {
        List<WorkFlowConditionDataVO> returnList = new ArrayList<>();

        List<User> list = userService.list(new QueryWrapper<User>().isNull("deleted_at").eq("status",1).orderByAsc("sort","id"));
        if(CollectionUtils.isNotEmpty(list))
            returnList = list.stream().map(item ->{
                WorkFlowConditionDataVO vo = new WorkFlowConditionDataVO();
                vo.setLabel(item.getName());
                vo.setValue(item.getId().toString());
                return vo;
            }).collect(Collectors.toList());

        return returnList;
    }

    @Override
    public List<WorkFlowConditionDataVO> getAllDepartmentData() {
        List<WorkFlowConditionDataVO> returnList = new ArrayList<>();

        List<Department> list = departmentService.list(new QueryWrapper<Department>().select(" id "," queryDepartmentNamesById(id) AS `name` ").isNull("deleted_at").eq("status",1).orderByAsc("pid","sort","id"));
        if(CollectionUtils.isNotEmpty(list))
            returnList = list.stream().map(item ->{
                WorkFlowConditionDataVO vo = new WorkFlowConditionDataVO();
                vo.setLabel(item.getName());
                vo.setValue(item.getId().toString());
                return vo;
            }).collect(Collectors.toList());

        return returnList;
    }

    @Override
    public List<WorkFlowConditionDataVO> getAllJobData() {
        List<WorkFlowConditionDataVO> returnList = new ArrayList<>();

        List<UserDepartmentRelation> list = userDepartmentRelationService.list(new QueryWrapper<UserDepartmentRelation>().select("distinct job"));
        if(CollectionUtils.isNotEmpty(list))
            returnList = list.stream().map(item ->{
                WorkFlowConditionDataVO vo = new WorkFlowConditionDataVO();
                vo.setLabel(item.getJob());
                vo.setValue(item.getJob());
                return vo;
            }).collect(Collectors.toList());

        return returnList;
    }

    @Override
    public List<WorkFlowConditionDataVO> getAllDepJobData() {
        List<WorkFlowConditionDataVO> returnList = new ArrayList<>();

        List<WorkFlowConditionForDepJobDTO> list = userDepartmentRelationService.getDepJobForWorkFlow();
        if(CollectionUtils.isNotEmpty(list)){
            Map<Long, List<WorkFlowConditionForDepJobDTO>> map = list.stream().collect(Collectors.groupingBy(WorkFlowConditionForDepJobDTO::getId));
            for(Map.Entry<Long, List<WorkFlowConditionForDepJobDTO>> entry : map.entrySet()){
                Long id = entry.getKey();
                List<WorkFlowConditionForDepJobDTO> jobs = entry.getValue();
                if(CollectionUtils.isNotEmpty(jobs)){
                    String dep = jobs.get(0).getName();

                    WorkFlowConditionDataVO vo = new WorkFlowConditionDataVO();
                    vo.setValue(id.toString());
                    vo.setLabel(dep);
                    List<WorkFlowConditionDataVO> children = jobs.stream().map(item -> {
                        WorkFlowConditionDataVO temp = new WorkFlowConditionDataVO();
                        temp.setLabel(item.getJob());
                        temp.setValue(id+"."+item.getJob());
                        return temp;
                    }).collect(Collectors.toList());
                    vo.setChildren(children);

                    returnList.add(vo);
                }
            }
        }
        return returnList;
    }

    @Override
    public Json getEditOptions(Integer form_module_id) {
        return baseMapper.getEditOptions(form_module_id);
    }

    @Override
    public Json getPropertyJson(Integer form_module_id) {
        return baseMapper.getPropertyJson(form_module_id);
    }

    @Override
    @Transactional
    public Boolean saveProcess(WorkFlowDefault data) {
        if(data.getId() != null){
            if(workFlowDefaultService.getById(data.getId()) != null) return workFlowDefaultService.updateById(data);
            else throw new CommonException("该流程不存在");
        }else{
            return workFlowDefaultService.save(data);
        }
    }
}
